/*
 * Copyright (C) 2025 Thomas Akehurst
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.tomakehurst.wiremock.db.service;

import com.github.tomakehurst.wiremock.common.Json;
import com.github.tomakehurst.wiremock.common.JsonException;
import com.github.tomakehurst.wiremock.db.entity.MultiMappingEntity;
import com.github.tomakehurst.wiremock.db.mapper.MultiMappingMapper;
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
import com.github.tomakehurst.wiremock.stubbing.StubMappingCollection;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

public class MultiMappingService {
  private final SqlSessionFactory sqlSessionFactory;

  public MultiMappingService(SqlSessionFactory sqlSessionFactory) {
    this.sqlSessionFactory = sqlSessionFactory;
  }

  // 新增多存根文件（批量导入时使用）
  public void save(String fileName, List<StubMapping> mappings) {
    try (SqlSession session = sqlSessionFactory.openSession(true)) {
      MultiMappingMapper mapper = session.getMapper(MultiMappingMapper.class);
      // 使用新构造函数初始化StubMappingCollection
      StubMappingCollection collection = new StubMappingCollection(mappings);
      // 序列化时仅包含mappings字段（避免父类StubMapping的多余字段干扰）
      String content = Json.writePrivate(collection);

      MultiMappingEntity entity = new MultiMappingEntity();
      entity.setId(UUID.randomUUID().toString());
      entity.setFileName(fileName);
      entity.setContent(content);
      entity.setCreatedAt(LocalDateTime.now());

      mapper.insert(entity);
    } catch (Exception e) { // 捕获序列化或数据库操作异常
      throw new RuntimeException("Failed to save multi-mapping: " + fileName, e);
    }
  }

  // 查询所有多存根文件，并解析为StubMapping列表
  public List<StubMapping> findAllAsStubMappings() {
    try (SqlSession session = sqlSessionFactory.openSession()) {
      MultiMappingMapper mapper = session.getMapper(MultiMappingMapper.class);
      List<MultiMappingEntity> entities = mapper.findAll();

      return entities.stream()
          .flatMap(
              entity -> {
                try {
                  // 反序列化JSON为StubMappingCollection
                  StubMappingCollection collection =
                      Json.read(entity.getContent(), StubMappingCollection.class);
                  // 通过getMappingOrMappings()获取所有存根（兼容单/多存根结构）
                  return collection.getMappingOrMappings().stream();
                } catch (JsonException e) {
                  // 处理单个文件解析失败（不影响其他文件）
                  throw new RuntimeException(
                      "Failed to parse multi-mapping file: " + entity.getFileName(), e);
                }
              })
          .collect(Collectors.toList());
    }
  }

  // 根据ID删除多存根文件
  public void deleteById(String id) {
    try (SqlSession session = sqlSessionFactory.openSession(true)) {
      MultiMappingMapper mapper = session.getMapper(MultiMappingMapper.class);
      mapper.deleteById(id);
    }
  }
}
